// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: jing

#include <utility>
#include <toml.hpp>

#include "coin2/exchange/base/feed/arbitration/arbitration_config.h"

namespace coin2::exchange::base::feed::arbitration {
namespace impl {

ArbitrationConfigMap::ArbitrationConfigMap(
  const coin2::flow::SymbolGroupConfig& symbol_groups,
  const std::experimental::filesystem::path& path)
{
  const auto table = toml::parse(path).as_table();

  for (const auto& pair : table) {
    ArbitrationConfig config;
    const auto& entry = pair.second.as_table();
    if (entry.find("window_size") != entry.end()) {
      config.window_size = entry.at("window_size").as_integer();
    } else {
      config.window_size = 1000;
    }

    auto mea = MarketExchangeApi::FromSnakeStringNoThrow(pair.first);
    if (!mea.has_value()) {
      continue;
    }
    std::vector<char> groups = symbol_groups.GetGroups(mea.value());
    for (auto g : groups) {
      config.group_window_sizes[g] = config.window_size;
    }
    if (entry.find("group_window_sizes") != entry.end()) {
      const auto& sizes = entry.at("group_window_sizes").as_table();
      for (const auto& [group, size] : sizes) {
        config.group_window_sizes[group[0]] = size.as_integer();
      }
    }

    configs_.insert(std::make_pair(mea.value(), config));
  }
}

int64_t ArbitrationConfigMap::GetWindowSize(const MarketExchangeApi& mea, char group) const
{
  auto it = configs_.find(mea);
  if (it == configs_.end()) {
    throw std::runtime_error("[ArbitrationConfigMap] cannot find mea: " + mea.SnakeString());
  }
  auto it_group = it->second.group_window_sizes.find(group);
  if (it_group == it->second.group_window_sizes.end()) {
    return 1;
  }
  return it_group->second;
}

int64_t ArbitrationConfigMap::GetWindowSize(const MarketExchangeApi& mea) const
{
  auto it = configs_.find(mea);
  if (it == configs_.end()) {
    throw std::runtime_error("[ArbitrationConfigMap] cannot find mea: " + mea.SnakeString());
  }

  return it->second.window_size;
}

}  // namespace impl
}  // namespace coin2::exchange::base::feed::arbitration
